home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / admin / xinetd.2 / xinetd / xinetd.2.1.7-linux.4 / libs / src / str / strs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-25  |  6.2 KB  |  305 lines

  1. /*
  2.  * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
  3.  * All rights reserved.  The file named COPYRIGHT specifies the terms 
  4.  * and conditions for redistribution.
  5.  */
  6.  
  7. static char RCSid[] = "$Id: strs.c,v 3.1 1993/06/13 02:50:39 panos Exp $" ;
  8.  
  9. #include <ctype.h>
  10. #include <memory.h>
  11. #include <varargs.h>
  12.  
  13. char *malloc() ;
  14.  
  15. #include "ss_impl.h"
  16.  
  17. /*
  18.  * NOTE: The brute force method (with the __strs_bfops) must be always 
  19.  *         available so that we can switch to it if another method fails.
  20.  */
  21. extern struct ss_ops __strs_bfops ;
  22. extern struct ss_ops __strs_rkops ;
  23. extern struct ss_ops __strs_kmpops ;
  24. extern struct ss_ops __strs_sbmops ;
  25. extern struct ss_ops __strs_bmhops ;
  26. extern struct ss_ops __strs_soops ;
  27.  
  28. /*
  29.  * NOTE: This table is arranged according to increasing method number.
  30.  *            This allows quick indexing into it using the user-provided
  31.  *            method as a hint:
  32.  *                if ( selection_table[ user_method ].method == user_method )
  33.  *                    FOUND
  34.  *                else
  35.  *                    DO SEQUENTIAL SEARCH
  36.  *            This allows both quick access and a change of method numbers
  37.  *            in the future without requiring recompilation of programs in
  38.  *            order to work with new versions of the library.
  39.  */
  40. static struct ss_select selection_table[] =
  41.     {
  42.         { STRS_BF,                    &__strs_bfops        },
  43.         { STRS_RK,                    &__strs_rkops        },
  44.         { STRS_KMP,                    &__strs_kmpops        },
  45.         { STRS_SBM,                    &__strs_sbmops        },
  46.         { STRS_BMH,                    &__strs_bmhops        },
  47.         { STRS_SO,                    &__strs_soops        },
  48.         { 0,                            0                        }
  49.     } ;
  50.  
  51. static char identity_map[ ALPHABET_SIZE ] ;
  52. static char upper_to_lower_map[ ALPHABET_SIZE ] ;
  53.  
  54. static int tables_initialized ;
  55.  
  56. /*
  57.  * This header is returned when an empty pattern is given to strs_setup.
  58.  * The rest of the functions check ss_patlen and do nothing if that is zero.
  59.  * ss_patlen in this header will be initialized to zero.
  60.  */
  61. static header_s empty_pattern_header ;
  62.  
  63.  
  64. PRIVATE void initialize_tables()
  65. {
  66.     int i ;
  67.  
  68.     for ( i = 0 ; i < sizeof( upper_to_lower_map ) ; i++ )
  69.     {
  70.         if ( isascii( i ) && isupper( i ) )
  71.             upper_to_lower_map[ i ] = i + 'a' - 'A' ;
  72.         else
  73.             upper_to_lower_map[ i ] = i ;
  74.         identity_map[ i ] = i ;
  75.     }
  76. }
  77.  
  78.  
  79. /*
  80.  * Initializes header
  81.  *
  82.  * Note that 'pattern' does not need to be a NUL-terminated string.
  83.  */
  84. PRIVATE int init( hp, flags, pattern, patlen )
  85.     register header_s        *hp ;
  86.     int                        flags ;
  87.     char                        *pattern ;
  88.     int                        patlen ;
  89. {
  90.     int requested_method = SS_GETMETHOD( flags ) ;
  91.     register struct ss_select *selp ;
  92.  
  93.     if ( ! tables_initialized )
  94.     {
  95.         initialize_tables() ;
  96.         tables_initialized = TRUE ;
  97.     }
  98.  
  99.     /*
  100.      * Initialize header fields
  101.      */
  102.     SS_FLAGS( hp ) = SS_GETFLAGS( flags ) ;
  103.     SS_PATLEN( hp ) = patlen ;
  104.     if ( SS_SWITCH( hp ) && patlen < 4 )
  105.         SS_OPS( hp ) = &__strs_bfops ;        /* brute force */
  106.     else
  107.     {
  108.         /*
  109.          * Determine ops
  110.          */
  111.         if ( selection_table[ requested_method ].sel_method == requested_method )
  112.             selp = &selection_table[ requested_method ] ;
  113.         else
  114.             for ( selp = &selection_table[ 0 ] ; selp->sel_ops ; selp++ )
  115.                 if ( requested_method == selp->sel_method )
  116.                     break ;
  117.         if ( selp->sel_ops )
  118.             SS_OPS( hp ) = selp->sel_ops ;
  119.         else if ( SS_SWITCH( hp ) )
  120.             SS_OPS( hp ) = &__strs_bfops ;        /* brute force */
  121.         else
  122.             return( SS_ERR ) ;
  123.     }
  124.  
  125.     if ( SS_MALLOC( hp ) )
  126.     {
  127.         SS_PATTERN( hp ) = malloc( (unsigned)SS_PATLEN( hp ) ) ;
  128.         if ( SS_PATTERN( hp ) == CHAR_NULL )
  129.         {
  130.             (void) free( (char *)hp ) ;
  131.             return( SS_ERR ) ;
  132.         }
  133.         (void) memcpy( SS_PATTERN( hp ), pattern, (int)SS_PATLEN( hp ) ) ;
  134.     }
  135.     else
  136.         SS_PATTERN( hp ) = pattern ;
  137.  
  138.     /*
  139.      * If the user asked for case-insensitive search, we create our own
  140.      * copy of the pattern in lower case. If the pattern is malloc'ed
  141.      * we overwrite, otherwise we malloc some memory and clear the
  142.      * STRS_NOMALLOC flag.
  143.      */
  144.     if ( SS_IGNCASE( hp ) )
  145.     {
  146.         char *new_pattern ;
  147.         register int i ;
  148.  
  149.         SS_SETMAP( hp, upper_to_lower_map ) ;
  150.  
  151.         if ( SS_MALLOC( hp ) )
  152.             new_pattern = SS_PATTERN( hp ) ;
  153.         else
  154.         {
  155.             new_pattern = malloc( (unsigned)SS_PATLEN( hp ) + 1 ) ;
  156.             if ( new_pattern == CHAR_NULL )
  157.                 return( SS_ERR ) ;
  158.             SS_SETMALLOC( hp ) ;            /* clears the STRS_NOMALLOC flag */
  159.         }
  160.         for ( i = 0 ; i < SS_PATLEN( hp ) ; i++ )
  161.             new_pattern[ i ] = SS_MAP( hp, SS_PATTERN( hp )[ i ] ) ;
  162.         SS_PATTERN( hp ) = new_pattern ;
  163.     }
  164.     else
  165.         SS_SETMAP( hp, identity_map ) ;
  166.  
  167.     for ( ;; )
  168.     {
  169.         if ( SS_SETUP( hp ) == SS_OK )
  170.             return( SS_OK ) ;
  171.         else
  172.         {
  173.             if ( ! SS_SWITCH( hp ) || SS_OPS( hp ) == &__strs_bfops )
  174.             {
  175.                 if ( SS_MALLOC( hp ) )
  176.                     (void) free( (char *)hp ) ;
  177.                 return( SS_ERR ) ;
  178.             }
  179.             SS_OPS( hp ) = &__strs_bfops ;
  180.         }
  181.     }
  182. }
  183.  
  184.  
  185. /*
  186.  * Finalize header
  187.  */
  188. PRIVATE void fini( hp )
  189.     header_s *hp ;
  190. {
  191.     SS_DONE( hp ) ;
  192.     if ( SS_MALLOC( hp ) )
  193.         (void) free( SS_PATTERN( hp ) ) ;
  194. }
  195.  
  196.  
  197. /*
  198.  * Create a search handle
  199.  */
  200. strs_h strs_setup( flags, pattern, va_alist )
  201.     int    flags ;
  202.     char    *pattern ;
  203.     va_dcl
  204. {
  205.     header_s        *hp ;
  206.     int            patlen ;
  207.     va_list        ap ;
  208.  
  209.     hp = HP( malloc( sizeof( *hp ) ) ) ;
  210.     if ( hp == NULL )
  211.         return( NULL_HANDLE ) ;
  212.     
  213.     if ( flags & STRS_PATLEN )
  214.     {
  215.         va_start( ap ) ;
  216.         patlen = va_arg( ap, int ) ;
  217.         va_end( ap ) ;
  218.     }
  219.     else
  220.         patlen = strlen( pattern ) ;
  221.  
  222.     if ( patlen == 0 )
  223.         return( (strs_h) &empty_pattern_header ) ;
  224.  
  225.     if ( init( hp, flags, pattern, patlen ) == SS_OK )
  226.         return( (strs_h)hp ) ;
  227.     else
  228.     {
  229.         free( (char *)hp ) ;
  230.         return( NULL_HANDLE ) ;
  231.     }
  232. }
  233.  
  234.  
  235. /*
  236.  * Destroy a search handle
  237.  */
  238. void strs_done( handle )
  239.     strs_h handle ;
  240. {
  241.     header_s *hp = HP( handle ) ;
  242.  
  243.     if ( SS_PATLEN( hp ) != 0 )
  244.     {
  245.         fini( hp ) ;
  246.         (void) free( (char *) handle ) ;
  247.     }
  248. }
  249.  
  250.  
  251. char *strs_match( handle, str, len )
  252.     strs_h    handle ;
  253.     char        *str ;
  254.     int        len ;
  255. {
  256.     register header_s *hp = HP( handle ) ;
  257.  
  258.     if ( SS_PATLEN( hp ) == 0 )
  259.         return( str ) ;
  260.     if ( SS_PATLEN( hp ) > len )
  261.         return( CHAR_NULL ) ;
  262.     return( SS_MATCH( hp, str, len ) ) ;
  263. }
  264.  
  265.  
  266.  
  267. char *strs_search( flags, str, len, pattern, va_alist )
  268.     int    flags ;
  269.     char    *str ;
  270.     int    len ;
  271.     char    *pattern ;            /* NUL-terminated */
  272.     va_dcl
  273. {
  274.     header_s        t_header ;
  275.     char            *p ;
  276.     int            patlen ;
  277.     va_list        ap ;
  278.  
  279.     if ( flags & STRS_PATLEN )
  280.     {
  281.         va_start( ap ) ;
  282.         patlen = va_arg( ap, int ) ;
  283.         va_end( ap ) ;
  284.     }
  285.     else
  286.         patlen = strlen( pattern ) ;
  287.  
  288.     if ( patlen == 0 )
  289.         return( str ) ;
  290.  
  291.     if ( patlen > len )
  292.         return( CHAR_NULL ) ;
  293.  
  294.     if ( init( &t_header, flags | STRS_NOMALLOC, pattern, patlen ) == SS_OK )
  295.     {
  296.         p = SS_MATCH( &t_header, str, len ) ;
  297.         fini( &t_header ) ;
  298.         return( p ) ;
  299.     }
  300.     else
  301.         return( CHAR_NULL ) ;
  302. }
  303.  
  304.  
  305.